昨天我們成功將服務部署上 Kubernetes,但是在部署過程中,需要手動逐一部署每個元件
有沒有可以透過一鍵部署,就可以快速部署服務的方法呢?答案是有的!
今天要介紹的是 Helm,從下圖官網的斗大標題可以得知,Helm 是一套專為 Kubernetes 而生的 Kubernetes Package Manager
▲ 圖取自 Helm 官網
透過將服務所需的 yaml 描述檔打包成 chart (也就是 Package),讓開發人員可以一鍵快速部署
下面我們就來實際操作看看吧
Helm 提供了多達 10 種以上的安裝方式
這邊我們選擇使用 Homebrew 來安裝
brew install helm
指令 | 用途 | 指令 | 用途 |
---|---|---|---|
helm create |
在本地建立 Helm chart | helm dependency |
管理 Helm chart 依賴 |
helm install |
安裝 Helm chart,安裝後會產生一個 release 版本 | helm lint |
驗證 Helm chart 語法、格式是否有誤 |
helm list |
列出所有的 release | helm package |
將本地的 Helm chart 進行打包 |
helm repo |
列出、新增、更新、刪除 Chart Repository | helm rollback |
將當前 release 版本回滾到先前版本 |
helm pull |
從遠端拉取 Helm chart 到本地 | helm search |
搜尋 Helm chart |
helm uninstall |
刪除 release 版本 | helm upgrade |
更新 release 版本 |
開啟 Terminal 並輸入以下指令
helm create <CHART_NAME>
# Example
helm create it15th
建立好 Helm chart 後,就可以看到像下面一樣的 Chart 資料夾結構了
下面就來說明每個檔案的用途
| it15th
--
|
-- charts // 用來存放依賴的 Sub Charts
|
-- templates // 用來存放每個元件的 yaml 檔
|
-- 每個元件的 yaml...
|
-- .helmignore // 用來定義 helm package 時,不會被打包進 Chart 內的東西
|
-- Chart.yaml // 記載這個 Helm chart 的相關資訊
|
-- values.yaml // 用來定義 templates 底下的各 yaml 檔的參數
Helm Official Documentation
https://helm.sh/docs/chart_template_guide/getting_started/
接下來我們可以先將昨天撰寫的各元件的 yaml 檔放到 templates 資料夾內
接著就可以到 values.yaml
內開始定義參數
pod:
metadata:
labels:
app: it15th-pod
spec:
containers:
name: it15th-container
image: leoho0722/it15th:k8s
ports:
containerPort: 8080
args: ["./it15th"]
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
deployment:
metadata:
name: it15th-deployment
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 2
minReadySeconds: 60
revisionHistoryLimit: 10
service:
metadata:
name: it15th-service
spec:
type: NodePort
ports:
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 32000
selector:
app: it15th-pod
pv:
metadata:
name: it15th-pv
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: it15th-pv
hostPath:
path: /mnt/data
type: DirectoryOrCreate
pvc:
metadata:
name: it15th-pvc
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 256Mi
storageClassName: it15th-pv
# Kubernetes 中 Deployment 元件的版本
apiVersion: apps/v1
# 該元件的類型
kind: Deployment
# 該元件的元資料
metadata:
# 這個 Deployment 的名稱
name: {{ .Values.deployment.metadata.name }}
# 這個 Deployment 的 DeploymentSpec
spec:
# 要建立的 Pod 數量
# 當現有 Pod 數量小於這邊 replica 設定的數值時,就會自動產生對應數量的 Pod 來補齊
replicas: {{ .Values.deployment.spec.replicas }}
# 將更新 Pod 取代舊有 Pod 的政策/策略
strategy:
# 這邊的 type 可以設定為 RollingUpdate 或 Recreate
# RollingUpdate 會逐一更新 Pod,不會將所有 Pod 都停止
# Recreate 會將所有 Pod 都停止,再重新建立新的 Pod
type: {{ .Values.deployment.spec.strategy.type }}
# 這邊的 maxSurge 設定為 1,表示在更新 Pod 時,最多可以多出 1 個 Pod
# 這邊的 maxUnavailable 設定為 0,表示在更新 Pod 時,最多可以少 0 個 Pod
rollingUpdate:
# 在 RollingUpdate 過程中,要多比 `replica` 設定的數量生幾個 Pod 出來
# 好處是,可以降低在 RollingUpdate 過程中,舊 Pod 內容出現的機率
maxSurge: {{ .Values.deployment.spec.strategy.rollingUpdate.maxSurge }}
# 在 RollingUpdate 過程中,可以允許多少數量的 Pod 無法使用
# 若 maxSurge 不為 0,maxUnavailable 也不得為 0
maxUnavailable: {{ .Values.deployment.spec.strategy.rollingUpdate.maxUnavailable }}
# 新建立出來的 Pod 如果沒有任何 Container Crash 的情形發生,
# 應準備就緒的最小秒數,預設為 0 (即 Pod 準備就緒後就可視為可用)
minReadySeconds: {{ .Values.deployment.spec.minReadySeconds }}
# 要保留多少數量可以 RollBack 的舊有 ReplicaSet,預設為 10
revisionHistoryLimit: {{ .Values.deployment.spec.revisionHistoryLimit }}
# 要選取的 Pod
selector:
matchLabels:
app: {{ .Values.pod.metadata.labels.app }}
# 選到的 Pod 的 PodTemplateSpec
template:
# Pod 的元資料
metadata:
# Pod 的標籤
labels:
app: {{ .Values.pod.metadata.labels.app }}
# 選取到的 Pod 的 PodSpec,用來定義 Pod 中的 Containers
spec:
# Pod 要執行的 Container
containers:
# 選取到的 Pod 內的 Container 名稱
- name: {{ .Values.pod.spec.containers.name }}
# 這個 Container 要用的 Image,預設從 DockerHub 取得
image: {{ .Values.pod.spec.containers.image }}
# 宣告這個 Container 要對外開放的 port 類型
ports:
# 宣告這個 Container 要對外開放的 port 號
- containerPort: {{ .Values.pod.spec.containers.ports.containerPort }}
# 宣告這個 Container 要執行的指令
args: {{ .Values.pod.spec.containers.args }}
# 宣告這個 Container 要用的資源
resources:
# 這個 Container 最多可以用到的資源
limits:
cpu: {{ .Values.pod.spec.containers.resources.limits.cpu }}
memory: {{ .Values.pod.spec.containers.resources.limits.memory }}
# 這個 Container 最少要用到的資源
requests:
cpu: {{ .Values.pod.spec.containers.resources.requests.cpu }}
memory: {{ .Values.pod.spec.containers.resources.requests.memory }}
# 宣告這個 Container 要用的 Volume
volumeMounts:
- name: {{ .Values.pv.metadata.name }}
mountPath: {{ .Values.pv.spec.hostPath.path }}
volumes:
- name: {{ .Values.pv.metadata.name }}
persistentVolumeClaim:
claimName: {{ .Values.pvc.metadata.name }}
# Kubernetes 中 Service 元件的版本號
apiVersion: v1
# 該元件的種類
kind: Service
# 該元件的元資料
metadata:
# 這個 Service 的名稱
name: {{ .Values.service.metadata.name }}
# 這個 Service 的 ServiceSpec
spec:
# Service 要以哪種模式運作
# Kubernetes 提供 ClusterIP、NodePort、ExternalName、LoadBalancer
# 預設為 ClusterIP
type: {{ .Values.service.spec.type }}
# 要選取的 Pod
selector:
app: {{ .Values.pod.metadata.labels.app }}
# 設定 Service 要連接的相關 port 號
ports:
- name: {{ .Values.pod.spec.containers.name}}
# 決定要以哪種網路協議來進行連線,TCP、UDP、SCTP
# 預設為 TCP
protocol: {{ .Values.service.spec.ports.protocol }}
# Service 要用哪個 port 號來連到 Pod
# 通常 port 會跟 targetPort 設定為相同的 port 號
port: {{ .Values.service.spec.ports.port }}
# Pod 對外開放的 port 號
# 沒設定 targetPort 的話,Kubernetes 預設會設為與 port 相同的 port 號
targetPort: {{ .Values.service.spec.ports.targetPort }}
# 指定外部連進 Service 的 port 號,範圍為 30000~32767
# 沒設定 nodePort 的話,Kubernetes 會自動指派一個範圍內的 port 號作為 nodePort
nodePort: {{ .Values.service.spec.ports.nodePort }}
# Kubernetes 中 PersistentVolume 元件的版本號
apiVersion: v1
# 該元件的種類
kind: PersistentVolume
# 該元件的元資料
metadata:
# 這個 PersistentVolume 的名稱
name: {{ .Values.pv.metadata.name }}
# 這個 PersistentVolume 的 PersistentVolumeSpec
spec:
# 該 PersistentVolume 的容量大小
capacity:
# 該 PersistentVolume 的容量大小單位
storage: {{ .Values.pv.spec.capacity.storage }}
# 該 PersistentVolume 的卷模式
volumeMode: {{ .Values.pv.spec.volumeMode }}
# 該 PersistentVolume 的存取模式
accessModes: {{ .Values.pv.spec.accessModes }}
# 該 PersistentVolume 的儲存類型
# 若不指定,則預設為 default 儲存類型
storageClassName: {{ .Values.pv.spec.storageClassName }}
# 該 PersistentVolume 位於主機上的儲存路徑
# 僅供單節點的 Kubernetes Cluster 使用
hostPath:
# 該 PersistentVolume 的儲存路徑
path: {{ .Values.pv.spec.hostPath.path }}
# 該 PersistentVolume 的儲存路徑的類型
type: {{ .Values.pv.spec.hostPath.type }}
# Kubernetes 中 PersistentVolumeClaim 元件的版本號
apiVersion: v1
# 該元件的種類
kind: PersistentVolumeClaim
# 該元件的元資料
metadata:
# 這個 PersistentVolumeClaim 的名稱
name: {{ .Values.pvc.metadata.name }}
# 這個 PersistentVolumeClaim 的 PersistentVolumeClaimSpec
spec:
# 要求的儲存空間大小
resources:
requests:
storage: {{ .Values.pvc.spec.resources.requests.storage }}
# 要求的儲存空間的卷模式
volumeMode: {{ .Values.pvc.spec.volumeMode }}
# 要求的儲存空間的存取模式
accessModes: {{ .Values.pvc.spec.accessModes }}
# 要求的儲存空間的儲存類型
storageClassName: {{ .Values.pvc.spec.storageClassName }}
用 values.yaml 改寫完原先的元件後,接下來就要來打包成 Helm chart 啦
在打包前,記得先進行 values.yaml 的語法/格式驗證
# 記得先切到 Chart 的目錄底下...
helm lint .
看到「0 chart(s) failed」就表示驗證成功啦,可以開始來打包了
# 記得先切到 Chart 的目錄底下...
helm package .
可以看到打包好的 Helm chart 以 tgz 壓縮檔的形式呈現
在 Terminal 輸入下面的 helm 指令
helm install it15th /Users/leoho/Desktop/it15th/kubernetes/it15th/it15th-1.0.0.tgz
如果覺得每次都要輸入這麼長的安裝指令,可以將 Helm chart 上傳到 Chart Repository,這樣就可以不用輸入這麼長了,這部分就交給大家自行實作了,官方文件連結在下方
Create Chart Repository - Helm Official Documentation
https://helm.sh/docs/topics/chart_repository/像是下面這樣
helm repo add {CHART_REPOSITORY_NAME} {CHART_REPOSITORY_URL} helm repo update helm install it15th {CHART_REPOSITORY_NAME}/it15th
接著輸入 kubectl get all
,就可以看到服務一樣正常執行
今天我們透過 Helm 這套專為 Kubernetes 應用而生的 Package Manager 將服務部署上 Kubernetes 上
只需要透過一個指令就能快速將整個 Kubernetes 應用部署到 Kubernetes 叢集內
明天就是最後一天了,來點輕鬆的,分享一下過去開始接觸「雲」這個東西的心得
我們明天見~